/**
 * @copyright 2015 Indie Semiconductor.
 *
 * This file is proprietary to Indie Semiconductor.
 * All rights reserved. Reproduction or distribution, in whole
 * or in part, is forbidden except by express written permission
 * of Indie Semiconductor.
 *
 * @file pwm_device.h
  */

#ifndef __PWM_DEVICE_H__
#define __PWM_DEVICE_H__

#include <stdint.h>
#include <stdbool.h>
#include "rugby.h"
#include "pmua_sfr.h"

#define PWM_CHANNEL_NUM    24

typedef enum {
 CURR_6MA = 0,
 CURR_30MA,
}CurrValue_t;

typedef void (*PwmIsrCallback_t)(uint8_t status);

typedef enum{
  PWM_PRESCALER_DIVIDE_1 = 0,
  PWM_PRESCALER_DIVIDE_2,
  PWM_PRESCALER_DIVIDE_4,
  PWM_PRESCALER_DIVIDE_8,
}PwmPrescaler_t;

typedef enum{
  PWM_CHANNEL_0 = 0,
  PWM_CHANNEL_1,
  PWM_CHANNEL_2,
  PWM_CHANNEL_3,
  PWM_CHANNEL_4,
  PWM_CHANNEL_5,
  PWM_CHANNEL_6,
  PWM_CHANNEL_7,
  PWM_CHANNEL_8,
  PWM_CHANNEL_9,
  PWM_CHANNEL_10,
  PWM_CHANNEL_11,
  PWM_CHANNEL_12,
  PWM_CHANNEL_13,
  PWM_CHANNEL_14,
  PWM_CHANNEL_15,
  PWM_CHANNEL_16,
  PWM_CHANNEL_17,
  PWM_CHANNEL_18,
  PWM_CHANNEL_19,
  PWM_CHANNEL_20,
  PWM_CHANNEL_21,
  PWM_CHANNEL_22,
  PWM_CHANNEL_23,
}PwmChannel_t;

typedef enum{
  PWM_TRIGGER_POS_EDGE = 0,
  PWM_TRIGGER_NEG_EDGE,
}PWMTriggerEdge_t;

typedef struct{
  PwmPrescaler_t divide;
  uint16_t       period;
  bool           invertEn;
  bool           enable;
}PwmConfig_t;

void PWM_Init(PwmPrescaler_t divide, uint16_t period, bool invertEn);
void PWM_SetMatchValue(PwmChannel_t channel, uint16_t matchRisingValue, uint16_t matchFaillValue);
void PWM_StartAndUpdate(void);
void PWM_RegisterPWMMatchIRQ(PwmChannel_t channel, PWMTriggerEdge_t edge, PwmIsrCallback_t callback);
void PWM_UnRegisterPWMMatchIRQ(PwmChannel_t channel);
void PWM_RegisterPWMReloadIRQ(PwmChannel_t channel, PwmIsrCallback_t callback);
void PWM_UnRegisterPWMReloadIRQ(PwmChannel_t channel);
void PWM_Enable(PwmChannel_t channel);
void PWM_Disable(PwmChannel_t channel);
void PWM_SetPrescaler(PwmChannel_t channel, PwmPrescaler_t divide);
void PWM_SetPeriod(PwmChannel_t channel, uint16_t period);
void PWM_SetInvert(PwmChannel_t channel, bool invertEn);
  
int8_t PWM_SetMaxChannelCurrent(PwmChannel_t channel, CurrValue_t current);

void PWM_EnableBuck(void);
#endif /* __PWM_DEVICE_H__  */